﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using JTest.BUS;
using JTest.Others;
using System.Threading;
using System.Collections;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using JTest.DTO;
using System.Xml;

namespace JTest.GUI
{
    /// <summary>
    /// @Author LuongGV
    /// </summary>
    public partial class frmImportDB : Form
    {
        private frmWait waitForm;
        List<string> lisTablesName = new List<string>();
        public frmImportDB()
        {
            InitializeComponent();
            waitForm = new frmWait(this);
            bkWorker.WorkerReportsProgress = true;
            controlLang();
        }


        /// @nhannc
        ///
        string yeucau = "";
        string message1 = "";
        string message2 = "";
        string message3 = "";
        string thongtin = "";
        string thatbai = "";
        string hoanthanh = "";
        string tuvung = "";
        string nguphap = "";
        string ofdtitle = "";
        string ofdfileName = "";
        string ofdOpen = "";
        string ofdCancel = "";
        private void controlLang()
        {
            try
            {
                XmlNodeList xnList = frmMain.xml.SelectNodes("lang/themcauhoi");
                foreach (XmlNode xn in xnList)
                {
                    this.Text = xn["title"].InnerText;
                    label1.Text = xn["nguon"].InnerText;
                    btnOpenFile.Text = xn["chontaptin"].InnerText;
                    lblForLevel.Text = xn["capdo"].InnerText;
                    lblForType.Text = xn["noidung"].InnerText;
                    tuvung = xn["tuvung"].InnerText;
                    nguphap = xn["nguphap"].InnerText;
                    label2.Text = xn["cachthuc"].InnerText;
                    rdExpand.Text = xn["morong"].InnerText;
                    lblForCSDL.Text = xn["csdl"].InnerText;
                    rdNew.Text = xn["taomoi"].InnerText;
                    lblForName.Text = xn["tencsdl"].InnerText;
                    btnApply.Text = xn["apdung"].InnerText;
                    btnExit.Text = xn["thoat"].InnerText;

                    yeucau = xn["yeucau"].InnerText;
                    message1 = xn["message1"].InnerText;
                    message2 = xn["message2"].InnerText;
                    message3 = xn["message3"].InnerText;
                    thongtin = xn["thongtin"].InnerText;
                    thatbai = xn["thatbai"].InnerText;
                    hoanthanh = xn["hoanthanh"].InnerText;

                    ofdtitle = xn["ofdtitle"].InnerText;
                    ofdfileName = xn["ofdfilename"].InnerText;
                    ofdOpen = xn["ofdOpen"].InnerText;
                    ofdCancel = xn["ofdCancel"].InnerText;
                }
            }
            catch (Exception ex) { 
                //MessageBox.Show(ex.Message); 
            }
        }

        /// <summary>
        /// Handles the Click event of the btnApply control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnApply_Click(object sender, EventArgs e)
        {
            // dic obj store param pass to bkworker.doWork
            Dictionary<string, object> args = new Dictionary<string, object>();

            //int level = (int)Enum.Parse(typeof(EnumLevel), cmbLevel.Text.ToString());
            int level = command.convertLevel(cmbLevel.Text.ToString());
            //string type = cmbType.Text.ToString();
            string type =command.convertType( cmbType.Text.ToString());
            string filePath = txtFilePath.Text;

            // Validate
            if (filePath.Length == 0)
            {
                MessageBox.Show(message1, yeucau, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (rdNew.Checked == true &&
                (txtName.Text.Length == 0 || (Regex.IsMatch(txtName.Text, "[\\\\/:;*?\"<>]"))))
            {
                MessageBox.Show(message2, yeucau, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtName.Text = "";
                txtName.Focus();
                return;
            }

            args.Add("level", level);
            args.Add("type", type);
            args.Add("filePath", filePath);

            if (rdExpand.Checked)
            {
                string db = cmbDbName.Text.ToString();
                args.Add("action", "insert");
                args.Add("db", db);

            }
            else if (rdNew.Checked)
            {
                string db = txtName.Text;
                args.Add("action", "new");
                args.Add("db", db);
            }

            // Display wait form
            if (waitForm.IsDisposed != false)
            {
                waitForm = new frmWait(this);
            }
            // center alignment
            waitForm.TopLevel = false;
            waitForm.Parent = this;
            waitForm.StartPosition = FormStartPosition.CenterParent;
            waitForm.Top = (this.Height - waitForm.Height) / 2;
            waitForm.Left = (this.Width - waitForm.Width) / 2;
            waitForm.Show();
            waitForm.BringToFront();
            pnlContainer.Enabled = false;

            bkWorker.RunWorkerAsync(args);

        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            ofdSource.Title = ofdtitle;

            if (ofdSource.ShowDialog() == DialogResult.OK)
            {
                txtFilePath.Text = ofdSource.FileName;
            }
        }

        private void frmImportDB_Load(object sender, EventArgs e)
        {
            // populate level and type datasource from enums
            cmbDbName.Items.Clear();
            cmbLevel.DataSource = EnumHelper.ToList(typeof(EnumLevel));
            cmbLevel.DisplayMember = "Key";
            cmbLevel.ValueMember = "Value";

            //cmbType.Items.Clear();
            //cmbType.DataSource = EnumHelper.ToList(typeof(EnumType));
            //cmbType.DisplayMember = "Key";
            //cmbType.ValueMember = "Value";

            cmbDbName.DataSource = SettingsBUS.loadDbaseSources();
            if(cmbDbName.Items.Count>0)
            cmbDbName.SelectedIndex = 0;
        }

        /// <summary>
        /// Handles the DoWork event of the bkWorker control.
        /// Call DataImportBUS to insert or create new database
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void bkWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Dictionary<string, object> agrs = (Dictionary<string, object>)e.Argument;
            string action = agrs["action"].ToString();
            string filePath = agrs["filePath"].ToString();
            string db = agrs["db"].ToString();
            string type = agrs["type"].ToString();
            int level = Int32.Parse(agrs["level"].ToString());
            StringBuilder builder = new StringBuilder();

            try
            {
                // load data in file
                List<QuestionDTO> list = DataImportBUS.getQuestionListFromExcel(filePath);
                if (list.Count == 0)
                {
                    list = DataImportBUS.getQuestionListFromStatisticalTables(filePath);
                    if (list.Count == 0)
                    {
                        throw new Exception(message3);
                    }
                }

                // Perform 
                if (action.Equals("insert"))
                {
                    // perform insert
                    int total = DataImportBUS.insertData(list, db, type, level);

                    // report to wait dialog
                    bkWorker.ReportProgress(100);

                    // Information to display
                    builder.AppendLine("Phương pháp : Thêm dữ liệu");
                    builder.AppendLine("CSDL : " + db);
                    builder.AppendLine("Loại : " + type);//EnumHelper.getDescription((Enum)Enum.Parse(typeof(EnumType), type)));
                    builder.AppendLine("Cấp độ : N" + level);
                    builder.AppendLine("Tổng số câu: " + total);
                    // return result
                    e.Result = builder.ToString();
                }
                else if (action.Equals("new"))
                {
                    // create new db 
                    string dbName = DataImportBUS.createNewDbase(db);
                    // perform insert
                    int total = DataImportBUS.insertData(list, dbName, type, level);

                    // report to wait dialog
                    bkWorker.ReportProgress(100);
                    Thread.Sleep(500);

                    // Information to Display
                    builder.AppendLine("Phương pháp : Tạo CSDL mới");
                    builder.AppendLine("CSDL : " + db);
                    builder.AppendLine("Loại : " + type);//EnumHelper.getDescription((Enum)Enum.Parse(typeof(EnumType), type)));
                    builder.AppendLine("Cấp độ : N" + level);
                    builder.AppendLine("Tổng số câu: " + total);
                    // return result
                    e.Result = builder.ToString();
                }
            }
            catch (Exception ex)
            {
                bkWorker.ReportProgress(50);
                e.Result = "failed";
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,MessageBoxDefaultButton.Button1);
            }
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the bkWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        private void bkWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            waitForm.Close();
            if (!e.Result.ToString().Equals("failed"))
            {
                MessageBox.Show(e.Result.ToString(), "Thông tin", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            resetControls();
            pnlContainer.Enabled = true;
        }

        /// <summary>
        /// Handles the CheckedChanged event of the rdExpand control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void rdExpand_CheckedChanged(object sender, EventArgs e)
        {
            if (cmbDbName.Enabled == false)
            {
                lblForCSDL.Enabled = true;
                cmbDbName.Enabled = true;
                txtName.Enabled = false;
                lblForName.Enabled = false;
            }
        }

        /// <summary>
        /// Handles the CheckedChanged event of the rdNew control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void rdNew_CheckedChanged(object sender, EventArgs e)
        {
            if (txtName.Enabled == false)
            {
                lblForName.Enabled = true;
                txtName.Enabled = true;
                cmbDbName.Enabled = false;
                lblForCSDL.Enabled = false;
            }
        }

        /// <summary>
        /// Resets the controls to default.
        /// </summary>
        private void resetControls()
        {
            // populate level and type datasource from enums
            cmbLevel.DataSource = EnumHelper.ToList(typeof(EnumLevel));
            cmbLevel.DisplayMember = "Key";
            cmbLevel.ValueMember = "Value";

            //cmbType.DataSource = EnumHelper.ToList(typeof(EnumType));
            //cmbType.DisplayMember = "Key";
            //cmbType.ValueMember = "Value";

            cmbDbName.DataSource = SettingsBUS.loadDbaseSources();
            cmbDbName.SelectedIndex = 0;

            txtName.Text = "";
            txtFilePath.Text = "";

            rdExpand.Checked = true;
        }

        /// <summary>
        /// Handles the ProgressChanged event of the bkWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.ProgressChangedEventArgs"/> instance containing the event data.</param>
        private void bkWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage < 100)
            {
                waitForm.InfoText = thatbai;
            }
            else
            {
                waitForm.InfoText = hoanthanh;
            }
        }

        private void cmbLevel_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (frmMain.lang != "error")
                {
                    try
                    {
                        cmbType.Items.Clear();

                        List<string> Type = command.getTypeList(cmbLevel.Text);

                        foreach (string strtype in Type)
                        {
                            cmbType.Items.Add(strtype);
                            //MessageBox.Show(strtype);
                        }
                        cmbType.SelectedIndex = 0;
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                // Todo: xu ly exception
            }
        }

    }
}
